Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit 4ac27014224b2736d264462a4829aad30dcb4873


Parents : 087fd6e
Author : Ivan <e46112d44649266d71fe2193e00a4710>
Signature : T66BB85Valid, signed by author
Date : 2026-07-24T05:12:19-05:00

chore: update community interfaces, tutorial flow, docs.

Changes
Diff

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9d1884d2..1987bfbe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
All notable changes to this project will be documented in this file.
-## [4.8.0] - 2026-07-TBD
+## [4.8.0] - 2026-07-25
### Added
@@ -28,7 +28,7 @@ All notable changes to this project will be documented in this file.
- Relay Chat room keys so hosts can require a key to join a room
- Desktop privacy: Windows screen security to omit MeshChatX from screenshots, recording, and Recall
- Android privacy options to block screenshots and clear the clipboard when backgrounded
-- Messages: **Copy image to clipboard** on the message and full-screen image context menus
+- Tutorial connect: **Internet + local (recommended)** adds AutoInterface and pre-selects 3 random community TCP bootstraps
- Remote management allow-list for identities that may query this instance with rnstatus/rnpath
- Post-install prompts for existing users after upgrades
- Coolify-oriented Docker Compose with resource limits for deployments
@@ -37,6 +37,10 @@ All notable changes to this project will be documented in this file.
### Changed
+- Tutorial privacy/security step: shorter mobile copy and toggle layout so labels and switches fit
+- Tutorial nav copy uses ASCII `->` instead of Unicode arrows
+- Community interface presets refreshed from directory.rns.recipes (69 online listings)
+- Bundled Reticulum manual refetch (reticulum_docs_bundle.json timestamp)
- Discovery map markers use dual-halo badge icons (peers, LXMF, discovered, tracking, stale) with banded cluster badges, zoom-gated labels, and cached styles for denser maps
- Map default basemap is OpenStreetMap (OSM). Style presets list OSM first and identity config wins over stale cached tile URLs
- UI opens sooner: HTTP binds first, Reticulum starts in the background

diff --git a/meshchatx.rsm b/meshchatx.rsm
index c21ac352..ff5ae418 100644
Binary files a/meshchatx.rsm and b/meshchatx.rsm differ

diff --git a/meshchatx/src/backend/data/community_interfaces.json b/meshchatx/src/backend/data/community_interfaces.json
index 938e412b..93bf3689 100644
--- a/meshchatx/src/backend/data/community_interfaces.json
+++ b/meshchatx/src/backend/data/community_interfaces.json
@@ -1,321 +1,477 @@
{
"_comment": "build_community_interfaces_json.py; source: directory.rns.recipes online listings. RNode omitted. Backbone without transport_identity -> TCPClientInterface. Optional override: public/community_interfaces.json.",
- "_source": "https://directory.rns.recipes/api/directory/submitted?search=&type=&status=online",
+ "_source": "https://directory.rns.recipes/api/directory/submitted?status=online",
"interfaces": [
{
- "name": "Beleth RNS Hub",
+ "name": "AT-Vienna-Backbone",
"type": "TCPClientInterface",
- "target_host": "rns.beleth.net",
+ "target_host": "rns.radical.computer",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "CRN IPv4 / IPv6",
+ "name": "Birdsnet BR",
"type": "TCPClientInterface",
- "target_host": "rns.noderage.org",
+ "target_host": "rns.birdsnet.com.br",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "Catz Node (TCP)",
+ "name": "Burger's Raspberry Pi",
"type": "TCPClientInterface",
- "target_host": "77.37.146.243",
+ "target_host": "188.169.142.232",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "Ether Whisperer",
+ "name": "Burger's backbone",
"type": "TCPClientInterface",
- "target_host": "132.145.75.143",
+ "target_host": "188.169.142.232",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "Ether Whisperer London",
+ "name": "Catz Node (TCP)",
"type": "TCPClientInterface",
- "target_host": "132.145.75.143",
+ "target_host": "77.37.146.243",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "Helsinki_IP_RNS_Node",
+ "name": "Cookies Node",
"type": "TCPClientInterface",
- "target_host": "rns.artdaw.com",
+ "target_host": "45.79.202.10",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Inertia.Chat",
"type": "TCPClientInterface",
"target_host": "use.inertia.chat",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "MSK SZAO (HaLow Bridge)",
+ "name": "LostInTheNet RSN",
"type": "TCPClientInterface",
- "target_host": "dreadgurizta.ru",
+ "target_host": "rns.studiorizzi.net",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "MichMesh",
"type": "TCPClientInterface",
"target_host": "rns.michmesh.net",
"target_port": 7822,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "QuikStop",
+ "name": "Nexus BackbonePH",
"type": "TCPClientInterface",
- "target_host": "167.114.185.21",
+ "target_host": "212.227.208.95",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "Quortal TCP Node",
+ "name": "QuikStop",
"type": "TCPClientInterface",
- "target_host": "reticulum.qortal.link",
+ "target_host": "167.114.185.21",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "R-Net TCP",
"type": "TCPClientInterface",
"target_host": "istanbul.reserve.network",
"target_port": 9034,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "RMAP",
"type": "TCPClientInterface",
"target_host": "rmap.world",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
- },
- {
- "name": "RNS Budapest(HU)",
- "type": "TCPClientInterface",
- "target_host": "vjs.hu",
- "target_port": 5858,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "RNS TCP Node Germany 001",
"type": "TCPClientInterface",
"target_host": "202.61.243.41",
"target_port": 4965,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "RNS TCP Node Germany 002",
"type": "TCPClientInterface",
"target_host": "193.26.158.230",
"target_port": 4965,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "RNS Testnet StoppedCold",
"type": "TCPClientInterface",
"target_host": "rns.stoppedcold.com",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "RNS Wiegand",
+ "type": "TCPClientInterface",
+ "target_host": "rns.wiegandtech.net",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "RNS_Transport_US-East",
"type": "TCPClientInterface",
"target_host": "45.77.109.86",
"target_port": 4965,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "SPAGOnet",
"type": "TCPClientInterface",
"target_host": "rns.pawgslayers.club",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Santino’s Testbed",
+ "type": "TCPClientInterface",
+ "target_host": "66.63.170.233",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Simply Equipped (US Cloud)",
"type": "TCPClientInterface",
"target_host": "rns.simplyequipped.com",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Slivovica",
"type": "TCPClientInterface",
"target_host": "213.235.65.180",
"target_port": 4440,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Sosnitz",
+ "type": "TCPClientInterface",
+ "target_host": "193.180.211.195",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "SparkN0de",
"type": "TCPClientInterface",
"target_host": "aspark.uber.space",
"target_port": 44860,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Sydney RNS",
+ "type": "TCPClientInterface",
+ "target_host": "sydney.reticulum.au",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Typenull",
+ "type": "TCPClientInterface",
+ "target_host": "rns.typenull.net",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "UTN Backbone",
+ "type": "TCPClientInterface",
+ "target_host": "rns.utn.lol",
+ "target_port": 4965,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "WDGWars Node",
+ "type": "TCPClientInterface",
+ "target_host": "rns.wdgwars.pl",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Washmesh",
+ "type": "TCPClientInterface",
+ "target_host": "reticulum.washmesh.net",
+ "target_port": 7242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "ZHULONG1 - Hong Kong Node",
+ "type": "TCPClientInterface",
+ "target_host": "103.195.4.226",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "bnZ-NODE01 (Gothenburg SE)",
"type": "TCPClientInterface",
"target_host": "91.207.113.250",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "carlos.node",
"type": "TCPClientInterface",
"target_host": "66.42.101.86",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "dismails TCP Interface",
"type": "TCPClientInterface",
"target_host": "rns.dismail.de",
"target_port": 7822,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "feather",
"type": "TCPClientInterface",
"target_host": "rns.feather.onl",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "g00n.cloud Hub",
"type": "TCPClientInterface",
"target_host": "dfw.us.g00n.cloud",
"target_port": 6969,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "jsreed5.org Reticulum Entrypoint",
+ "type": "TCPClientInterface",
+ "target_host": "jsreed5.org",
+ "target_port": 8256,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "lakakhara's rns",
+ "type": "TCPClientInterface",
+ "target_host": "46.17.104.181",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "meshage.me",
+ "type": "TCPClientInterface",
+ "target_host": "rns.meshage.me",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "mobilefabrik TCP",
"type": "TCPClientInterface",
"target_host": "phantom.mobilefabrik.com",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "noDNS1",
"type": "TCPClientInterface",
"target_host": "202.61.243.41",
"target_port": 4965,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "reticulum.hardenedbsd.org",
+ "name": "reticulum.me",
"type": "TCPClientInterface",
- "target_host": "reticulum.hardenedbsd.org",
+ "target_host": "reticulum.me",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "rns.noderage.org (IPv4 / IPv6)",
+ "name": "rns.h.acked.co.uk",
"type": "TCPClientInterface",
- "target_host": "rns.noderage.org",
+ "target_host": "188.166.83.139",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "www.vanheusden.com",
+ "name": "rns.not-a-number.io",
"type": "TCPClientInterface",
- "target_host": "vps001.vanheusden.com",
+ "target_host": "rns.not-a-number.io",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "wisco.network - tcp",
+ "type": "TCPClientInterface",
+ "target_host": "rns.wisco.network",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "zer0bitz | IPv4/6",
+ "type": "TCPClientInterface",
+ "target_host": "zer0bitz.ddns.net",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Beleth RNS Hub - Yggdrasil",
"type": "TCPClientInterface",
"target_host": "202:c6ff:5e33:94ca:512f:b192:36f3:1045",
"target_port": 4343,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Beleth Yggdrasil",
"type": "TCPClientInterface",
"target_host": "200:3953:999b:282e:e526:bcd2:c329:31a",
"target_port": 4343,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Catz Node Ygg",
+ "type": "TCPClientInterface",
+ "target_host": "202:dcd9:981a:4f12:1618:1066:13e2:8610",
+ "target_port": 4343,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Mike node",
+ "type": "TCPClientInterface",
+ "target_host": "200:186d:b8ad:799b:1146:2f3e:e58a:7478",
+ "target_port": 4242,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Spaceman-ygg",
"type": "TCPClientInterface",
"target_host": "201:e73a:61ee:ca68:4bc5:99d5:fd70:ded1",
"target_port": 4343,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Triplebit_Minneapolis_B-Yggdrasil",
"type": "TCPClientInterface",
"target_host": "201:1160:3f65:28ea:22b2:efb:a3c0:e012",
"target_port": 9055,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "ZHULONG1 - YGG - Hong Kong Node",
+ "type": "TCPClientInterface",
+ "target_host": "200:50e5:b8a1:35ce:f51:5456:8f1a:69ae",
+ "target_port": 4243,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "cea yggdrasil",
"type": "TCPClientInterface",
"target_host": "200:cea:10:1b1:3c23:3bc:34c1:8c82",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "kemerovo ygg",
"type": "TCPClientInterface",
"target_host": "203:f54a:ffa2:650d:df9d:1473:5228:94dc",
"target_port": 43434,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "rothbard_RNS_transport_ZA_ygg",
"type": "TCPClientInterface",
"target_host": "200:73eb:2e4:14be:aac7:90b3:784b:71a3",
"target_port": 4242,
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "wisco.network - yggdrasil",
+ "type": "TCPClientInterface",
+ "target_host": "203:b028:b702:aec4:4571:cf81:cb7a:8223",
+ "target_port": 4343,
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "zer0bitz | yggdrasil",
+ "type": "TCPClientInterface",
+ "target_host": "201:3de8:d5da:bc84:85e0:80e:680a:60c8",
+ "target_port": 4343,
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Casbah I2P Relay",
"type": "I2PInterface",
"i2p_peers": ["nckymqd5qchedbvjqsrlovgwc5iupasu3jjnt7fwws5vd4l552yq.b32.i2p"],
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Catz Node",
"type": "I2PInterface",
"i2p_peers": ["namcoiawqes3rdrvazab6war2dui2isuuh5alfdds6xtb3febmca.b32.i2p"],
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "Catz Node I2P",
+ "type": "I2PInterface",
+ "i2p_peers": ["f77ptezksg4qr4rdike5t2kj3hh2oa7l7qmohqwow6uc6evzjjtq.b32.i2p"],
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "DsecT",
+ "type": "I2PInterface",
+ "i2p_peers": ["ohugriah6z7s4tzeqbtaj7r7qcj4dcodudusilq445rh3xv2p3ra.b32.i2p"],
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "Kor's Node",
"type": "I2PInterface",
"i2p_peers": ["cknv7n3fnwlpq3uxb466c55d3onfj3wl6yfaqfcalbu5zefxizkq.b32.i2p"],
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
- "name": "RNS Oren I2P",
+ "name": "QC Backbone PH",
"type": "I2PInterface",
- "i2p_peers": ["q6qth2xl5fisekhvm2lbplprwaof4plkbh4cthjnlj2pck7ahp5q.b32.i2p"],
- "description": "directory.rns.recipes (user-submitted, online)"
+ "i2p_peers": ["ii2ocupidjezvgrxsapedqjnjdcjrkuyzqqspuwbqqtx6tahqsq.b32.i2p"],
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "SparkN0de I2P",
"type": "I2PInterface",
"i2p_peers": ["ccrlk4gdxkgrqr633b4msujteaf7gnqw5akxjiek5dhoosfmrdka.b32.i2p"],
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "ZHULONG1 - I2P - Hong Kong Node",
+ "type": "I2PInterface",
+ "i2p_peers": ["ikggyuyzmipveifdirq4cvyn64qpzgk3sukbccjw5wqnkknwlkaa.b32.i2p"],
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "akku i2p",
"type": "I2PInterface",
"i2p_peers": ["j4qvsmifjuq2fqn4wj34xu7swgqjyror4hx3qgl3aj3ggxmg6hrq.b32.i2p"],
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
},
{
"name": "rothbard_RNS_transport_ZA_i2p",
"type": "I2PInterface",
"i2p_peers": ["guuahj7pyb6ksmjv2bqrjg4cs2wou6cor3ivsi6crntqbzsxnbna.b32.i2p"],
- "description": "directory.rns.recipes (user-submitted, online)"
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "zer0bitz | i2p",
+ "type": "I2PInterface",
+ "i2p_peers": ["gdludub7eejnh3hhdtofakibaxmkivm5zjfl2zdxxd7btt6l4rkq.b32.i2p"],
+ "description": "directory.rns.recipes (online submitted + discovered)"
+ },
+ {
+ "name": "℮ ecce toronto i2p gateway ℮",
+ "type": "I2PInterface",
+ "i2p_peers": ["iifgzpiinws5jx5qpilph2nj4pnmoe3jdx2nbqa7twjukxskydoq.b32.i2p"],
+ "description": "directory.rns.recipes (online submitted + discovered)"
}
]
}

diff --git a/meshchatx/src/frontend/components/TutorialModal.vue b/meshchatx/src/frontend/components/TutorialModal.vue
index e99bb0f3..9fd31653 100644
--- a/meshchatx/src/frontend/components/TutorialModal.vue
+++ b/meshchatx/src/frontend/components/TutorialModal.vue
@@ -389,6 +389,34 @@
</div>
<div class="grid grid-cols-1 gap-4">
+ <button
+ type="button"
+ class="text-left flex items-start gap-4 p-5 rounded-2xl bg-indigo-500/5 dark:bg-indigo-500/10 border-2 transition-all"
+ :class="[
+ connectionMode === 'recommended'
+ ? 'border-indigo-500 ring-2 ring-indigo-500/30'
+ : 'border-indigo-500/20 hover:border-indigo-500',
+ ]"
+ :disabled="addingRecommended || savingDiscovery || addingLocal || reloadingReticulum"
+ @click="useRecommendedMode"
+ >
+ <v-icon icon="mdi-access-point-network" color="indigo" size="40"></v-icon>
+ <div class="flex-1 min-w-0">
+ <div class="font-bold text-lg text-gray-900 dark:text-white">
+ {{ $t("tutorial.mode_recommended_title") }}
+ </div>
+ <div class="text-sm text-gray-600 dark:text-zinc-400 mt-1">
+ {{ $t("tutorial.mode_recommended_desc") }}
+ </div>
+ </div>
+ <v-progress-circular
+ v-if="addingRecommended"
+ indeterminate
+ size="20"
+ width="2"
+ ></v-progress-circular>
+ </button>
+
<button
type="button"
class="text-left flex items-start gap-4 p-5 rounded-2xl bg-blue-500/5 dark:bg-blue-500/10 border-2 transition-all"
@@ -397,7 +425,7 @@
? 'border-blue-500 ring-2 ring-blue-500/30'
: 'border-blue-500/20 hover:border-blue-500',
]"
- :disabled="savingDiscovery"
+ :disabled="savingDiscovery || addingRecommended"
@click="useDiscoveryMode"
>
<v-icon icon="mdi-radar" color="blue" size="40"></v-icon>
@@ -425,7 +453,7 @@
? 'border-emerald-500 ring-2 ring-emerald-500/30'
: 'border-emerald-500/20 hover:border-emerald-500',
]"
- :disabled="addingLocal || reloadingReticulum"
+ :disabled="addingLocal || addingRecommended || reloadingReticulum"
@click="useLocalMode"
>
<v-icon icon="mdi-lan" color="emerald" size="40"></v-icon>
@@ -1508,7 +1536,33 @@
</p>
</div>
- <div class="grid grid-cols-1 md:grid-cols-3 gap-6 max-w-6xl mx-auto">
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-6xl mx-auto">
+ <button
+ type="button"
+ class="text-left flex flex-col gap-4 p-8 rounded-3xl bg-indigo-500/5 dark:bg-indigo-500/10 border-2 transition-all hover:scale-[1.02]"
+ :class="[
+ connectionMode === 'recommended'
+ ? 'border-indigo-500 ring-2 ring-indigo-500/30'
+ : 'border-indigo-500/20 hover:border-indigo-500',
+ ]"
+ :disabled="addingRecommended || savingDiscovery || addingLocal || reloadingReticulum"
+ @click="useRecommendedMode"
+ >
+ <v-icon icon="mdi-access-point-network" color="indigo" size="56"></v-icon>
+ <div class="font-bold text-xl text-gray-900 dark:text-white">
+ {{ $t("tutorial.mode_recommended_title") }}
+ </div>
+ <div class="text-sm text-gray-600 dark:text-zinc-400">
+ {{ $t("tutorial.mode_recommended_desc") }}
+ </div>
+ <v-progress-circular
+ v-if="addingRecommended"
+ indeterminate
+ size="20"
+ width="2"
+ ></v-progress-circular>
+ </button>
+
<button
type="button"
class="text-left flex flex-col gap-4 p-8 rounded-3xl bg-blue-500/5 dark:bg-blue-500/10 border-2 transition-all hover:scale-[1.02]"
@@ -1517,7 +1571,7 @@
? 'border-blue-500 ring-2 ring-blue-500/30'
: 'border-blue-500/20 hover:border-blue-500',
]"
- :disabled="savingDiscovery"
+ :disabled="savingDiscovery || addingRecommended"
@click="useDiscoveryMode"
>
<v-icon icon="mdi-radar" color="blue" size="56"></v-icon>
@@ -1543,7 +1597,7 @@
? 'border-emerald-500 ring-2 ring-emerald-500/30'
: 'border-emerald-500/20 hover:border-emerald-500',
]"
- :disabled="addingLocal || reloadingReticulum"
+ :disabled="addingLocal || addingRecommended || reloadingReticulum"
@click="useLocalMode"
>
<v-icon icon="mdi-lan" color="emerald" size="56"></v-icon>
@@ -2350,6 +2404,7 @@ export default {
bootstrapCommunitySectionOpen: true,
bootstrapAutoPickDone: false,
pickingRandomBootstraps: false,
+ addingRecommended: false,
migrationOffer: null,
migrationBusy: false,
androidStorageSetup: null,
@@ -2785,12 +2840,57 @@ export default {
this.reloadingReticulum = false;
}
},
+ async useRecommendedMode() {
+ if (this.addingRecommended) {
+ return;
+ }
+ this.addingRecommended = true;
+ try {
+ await window.api.post("/api/v1/reticulum/interfaces/add", {
+ name: "Local Network",
+ type: "AutoInterface",
+ enabled: true,
+ });
+ this.interfaceAddedViaTutorial = true;
+ GlobalState.hasPendingInterfaceChanges = true;
+ GlobalState.modifiedInterfaceNames.add("Local Network");
+
+ const payload = {
+ discover_interfaces: true,
+ autoconnect_discovered_interfaces: 3,
+ default_bootstrap_only: false,
+ };
+ await window.api.patch(`/api/v1/reticulum/discovery`, payload);
+ this.defaultBootstrapOnly = false;
+
+ ToastUtils.success(this.$t("tutorial.mode_recommended_added"));
+ this.connectionMode = "recommended";
+ this.currentStep = 4;
+ this.bootstrapListSearch = "";
+ this.bootstrapDiscoveredSectionOpen = true;
+ this.bootstrapCommunitySectionOpen = true;
+ this.bootstrapAutoPickDone = false;
+ await this.loadCommunityInterfaces();
+ await this.loadDiscoveredInterfaces();
+ await this.pickRandomTcpBootstraps({ silent: true, auto: true, count: 3 });
+ this.bootstrapAutoPickDone = true;
+ } catch (e) {
+ console.error("Failed to apply recommended connection mode:", e);
+ ToastUtils.error(
+ e.response?.data?.message ||
+ this.$t("tutorial.failed_add_local") ||
+ this.$t("tutorial.failed_enable_discovery")
+ );
+ } finally {
+ this.addingRecommended = false;
+ }
+ },
async useDiscoveryMode() {
this.savingDiscovery = true;
try {
const payload = {
discover_interfaces: true,
- autoconnect_discovered_interfaces: 4,
+ autoconnect_discovered_interfaces: 3,
default_bootstrap_only: false,
};
await window.api.patch(`/api/v1/reticulum/discovery`, payload);
@@ -2988,7 +3088,8 @@ export default {
return;
}
this.shuffleArrayInPlace(entries);
- const take = Math.min(4, entries.length);
+ const wanted = Number.isFinite(options.count) ? Number(options.count) : 3;
+ const take = Math.min(Math.max(1, wanted), entries.length);
this.selectedBootstrapKeys = entries.slice(0, take).map((e) => e.key);
const labels = this.selectedBootstrapKeys.map((k) => this.bootstrapDisplayLabelForKey(k));
if (!silent && !auto) {

diff --git a/meshchatx/src/frontend/components/TutorialPrivacyStep.vue b/meshchatx/src/frontend/components/TutorialPrivacyStep.vue
index 9a4830bf..19252497 100644
--- a/meshchatx/src/frontend/components/TutorialPrivacyStep.vue
+++ b/meshchatx/src/frontend/components/TutorialPrivacyStep.vue
@@ -1,99 +1,72 @@
<!-- SPDX-License-Identifier: 0BSD -->
<template>
- <div class="space-y-6" :class="compact ? '' : 'py-4'">
- <div class="space-y-2 text-center sm:text-left">
- <h2 class="text-2xl sm:text-3xl font-black text-gray-900 dark:text-white">
+ <div class="tutorial-privacy" :class="compact ? 'tutorial-privacy--compact' : ''">
+ <div class="tutorial-privacy__intro">
+ <h2 class="tutorial-privacy__title">
{{ $t("tutorial.privacy_title") }}
</h2>
- <p class="text-base text-gray-600 dark:text-zinc-400 max-w-xl">
+ <p class="tutorial-privacy__desc">
{{ $t("tutorial.privacy_desc") }}
</p>
</div>
- <div class="space-y-3 w-full max-w-xl mx-auto sm:mx-0">
- <div
- v-if="showWindowsScreenSecurity"
- class="p-4 rounded-2xl border border-amber-200 dark:border-amber-900/50 bg-amber-50/90 dark:bg-amber-950/40 text-left space-y-3"
- >
- <div class="font-semibold text-amber-950 dark:text-amber-100">
+ <div class="tutorial-privacy__list">
+ <div v-if="showWindowsScreenSecurity" class="tutorial-privacy__callout">
+ <div class="tutorial-privacy__callout-title">
{{ $t("app.screen_security_drm_eyebrow") }}
</div>
- <p class="text-sm text-amber-950/90 dark:text-amber-100/90">
- {{ $t("app.screen_security_description") }}
+ <p class="tutorial-privacy__callout-body">
+ {{ $t("tutorial.privacy_screen_security_desc") }}
</p>
- <p class="text-xs text-amber-950/80 dark:text-amber-100/80">
- {{ $t("app.screen_security_drm_note") }}
- </p>
- <label class="setting-toggle">
- <Toggle
- id="tutorial-screen-security"
- v-model="screenSecurityEnabled"
- :disabled="screenSecuritySaving"
- @update:model-value="onScreenSecurityChange"
- />
- <span class="setting-toggle__label">
- <span class="setting-toggle__title">{{ $t("app.screen_security_enabled") }}</span>
- <span class="setting-toggle__description">{{
- $t("app.screen_security_description_short")
- }}</span>
- </span>
- </label>
+ <SettingToggleRow
+ id="tutorial-screen-security"
+ v-model="screenSecurityEnabled"
+ :title="$t('app.screen_security_enabled')"
+ :description="$t('app.screen_security_description_short')"
+ :disabled="screenSecuritySaving"
+ @update:model-value="onScreenSecurityChange"
+ />
</div>
- <label v-if="showAndroidScreenshotBlock" class="setting-toggle">
- <Toggle
- id="tutorial-android-block-screenshots"
- v-model="androidBlockScreenshots"
- :disabled="androidSaving"
- @update:model-value="onAndroidBlockScreenshotsChange"
- />
- <span class="setting-toggle__label">
- <span class="setting-toggle__title">{{ $t("settings.android_block_screenshots") }}</span>
- <span class="setting-toggle__description">{{ $t("settings.android_block_screenshots_desc") }}</span>
- </span>
- </label>
+ <SettingToggleRow
+ v-if="showAndroidScreenshotBlock"
+ id="tutorial-android-block-screenshots"
+ v-model="androidBlockScreenshots"
+ :title="$t('settings.android_block_screenshots')"
+ :description="$t('tutorial.privacy_android_screenshots_desc')"
+ :disabled="androidSaving"
+ @update:model-value="onAndroidBlockScreenshotsChange"
+ />
- <label class="setting-toggle">
- <Toggle
- id="tutorial-obfuscate-hops"
- v-model="localHopsDelta"
- :disabled="reticulumSaving"
- @update:model-value="onLocalHopsDeltaChange"
- />
- <span class="setting-toggle__label">
- <span class="setting-toggle__title">{{ $t("app.obfuscate_hops") }}</span>
- <span class="setting-toggle__description">{{ $t("app.obfuscate_hops_description") }}</span>
- </span>
- </label>
+ <SettingToggleRow
+ id="tutorial-obfuscate-hops"
+ v-model="localHopsDelta"
+ :title="$t('app.obfuscate_hops')"
+ :description="$t('tutorial.privacy_obfuscate_hops_desc')"
+ :disabled="reticulumSaving"
+ @update:model-value="onLocalHopsDeltaChange"
+ />
- <label class="setting-toggle">
- <Toggle
- id="tutorial-privacy-mode"
- v-model="privacyModeEnabled"
- :disabled="configSaving"
- @update:model-value="onPrivacyModeChange"
- />
- <span class="setting-toggle__label">
- <span class="setting-toggle__title">{{ $t("app.privacy_mode_enabled") }}</span>
- <span class="setting-toggle__description">{{ $t("app.privacy_mode_description") }}</span>
- </span>
- </label>
+ <SettingToggleRow
+ id="tutorial-privacy-mode"
+ v-model="privacyModeEnabled"
+ :title="$t('app.privacy_mode_enabled')"
+ :description="$t('tutorial.privacy_mode_desc')"
+ :disabled="configSaving"
+ @update:model-value="onPrivacyModeChange"
+ />
- <label class="setting-toggle">
- <Toggle
- id="tutorial-telemetry"
- v-model="telemetryEnabled"
- :disabled="configSaving"
- @update:model-value="onTelemetryChange"
- />
- <span class="setting-toggle__label">
- <span class="setting-toggle__title">{{ $t("app.telemetry_enabled") }}</span>
- <span class="setting-toggle__description">{{ $t("app.telemetry_description") }}</span>
- </span>
- </label>
+ <SettingToggleRow
+ id="tutorial-telemetry"
+ v-model="telemetryEnabled"
+ :title="$t('app.telemetry_enabled')"
+ :description="$t('tutorial.privacy_telemetry_desc')"
+ :disabled="configSaving"
+ @update:model-value="onTelemetryChange"
+ />
</div>
- <p class="text-xs text-center sm:text-left text-gray-500 dark:text-zinc-500 max-w-xl">
+ <p class="tutorial-privacy__hint">
{{ $t("tutorial.privacy_later_hint") }}
</p>
</div>
@@ -103,12 +76,12 @@
import ElectronUtils from "../js/ElectronUtils.js";
import AndroidBridge from "../js/rnode/AndroidBridge.js";
import ToastUtils from "../js/ToastUtils";
-import Toggle from "./forms/Toggle.vue";
+import SettingToggleRow from "./settings/SettingToggleRow.vue";
export default {
name: "TutorialPrivacyStep",
components: {
- Toggle,
+ SettingToggleRow,
},
props: {
compact: {
@@ -272,3 +245,54 @@ export default {
},
};
</script>
+
+<style scoped>
+.tutorial-privacy {
+ @apply space-y-4;
+}
+.tutorial-privacy--compact {
+ @apply space-y-3;
+}
+.tutorial-privacy__intro {
+ @apply space-y-1 text-center sm:text-left;
+}
+.tutorial-privacy__title {
+ @apply text-xl sm:text-2xl font-black text-gray-900 dark:text-white;
+}
+.tutorial-privacy__desc {
+ @apply text-sm text-gray-600 dark:text-zinc-400 max-w-xl mx-auto sm:mx-0;
+}
+.tutorial-privacy__list {
+ @apply space-y-2 w-full max-w-xl mx-auto sm:mx-0;
+}
+.tutorial-privacy__callout {
+ @apply p-3 rounded-2xl border border-amber-200 dark:border-amber-900/50 bg-amber-50/90 dark:bg-amber-950/40 text-left space-y-2;
+}
+.tutorial-privacy__callout-title {
+ @apply text-sm font-semibold text-amber-950 dark:text-amber-100;
+}
+.tutorial-privacy__callout-body {
+ @apply text-xs text-amber-950/90 dark:text-amber-100/90;
+}
+.tutorial-privacy__hint {
+ @apply text-xs text-center sm:text-left text-gray-500 dark:text-zinc-500 max-w-xl mx-auto sm:mx-0;
+}
+.tutorial-privacy :deep(.setting-toggle) {
+ @apply relative flex flex-row-reverse items-start gap-3 rounded-2xl border border-gray-200 dark:border-zinc-800 bg-white/70 dark:bg-zinc-900/70 px-3 py-2.5;
+}
+.tutorial-privacy :deep(.setting-toggle > label) {
+ @apply shrink-0 self-start mt-0.5;
+}
+.tutorial-privacy :deep(.setting-toggle .sr-only) {
+ @apply absolute w-px h-px p-0 -m-px overflow-hidden whitespace-nowrap border-0;
+}
+.tutorial-privacy :deep(.setting-toggle__label) {
+ @apply flex-1 min-w-0 flex flex-col gap-0.5;
+}
+.tutorial-privacy :deep(.setting-toggle__title) {
+ @apply text-sm font-semibold text-gray-900 dark:text-white break-words leading-snug;
+}
+.tutorial-privacy :deep(.setting-toggle__description) {
+ @apply text-xs text-gray-600 dark:text-gray-300 break-words leading-snug;
+}
+</style>

diff --git a/meshchatx/src/frontend/components/settings/SettingToggleRow.vue b/meshchatx/src/frontend/components/settings/SettingToggleRow.vue
index caa31338..1575ec53 100644
--- a/meshchatx/src/frontend/components/settings/SettingToggleRow.vue
+++ b/meshchatx/src/frontend/components/settings/SettingToggleRow.vue
@@ -55,3 +55,27 @@ export default {
emits: ["update:modelValue"],
};
</script>
+
+<style scoped>
+.setting-toggle {
+ @apply relative flex flex-row-reverse items-start gap-3 rounded-2xl border border-gray-200 dark:border-zinc-800 bg-white/70 dark:bg-zinc-900/70 px-3 py-3;
+}
+.setting-toggle > :deep(label) {
+ @apply shrink-0 self-center;
+}
+.setting-toggle :deep(.sr-only) {
+ @apply absolute w-px h-px p-0 -m-px overflow-hidden whitespace-nowrap border-0;
+}
+.setting-toggle__label {
+ @apply flex-1 min-w-0 flex flex-col gap-0.5;
+}
+.setting-toggle__title {
+ @apply text-sm font-semibold text-gray-900 dark:text-white break-words leading-snug;
+}
+.setting-toggle__description {
+ @apply text-xs sm:text-sm text-gray-600 dark:text-gray-300 break-words leading-snug;
+}
+.setting-toggle__hint {
+ @apply text-xs text-gray-500 dark:text-gray-400 break-words;
+}
+</style>

diff --git a/meshchatx/src/frontend/locales/de.json b/meshchatx/src/frontend/locales/de.json
index 401bf186..bb8f849b 100644
--- a/meshchatx/src/frontend/locales/de.json
+++ b/meshchatx/src/frontend/locales/de.json
@@ -3114,8 +3114,8 @@
"i18n_desc_page": "Vollständige Internationalisierungsunterstützung für die Sprachen Englisch, Deutsch, Italienisch, Russisch, Niederländisch, Französisch und Spanisch.",
"more_features": "+ viele weitere Funktionen!",
"connect": "Mit dem Mesh verbinden",
- "connect_desc": "Wählen Sie, wie Sie sich verbinden möchten. Discovery und Bootstrap-Knoten können später auf der Schnittstellen-Seite konfiguriert werden.",
- "connect_desc_page": "Nutzen Sie lokale LAN-Erkennung oder konfigurieren Sie eigene Schnittstellen auf der Schnittstellen-Seite. Auto-Discovery und Bootstrap-Knoten stehen dort für die erweiterte Einrichtung zur Verfügung.",
+ "connect_desc": "Empfohlen: Internet + lokal (AutoInterface plus 3 Community-TCP-Knoten). Später änderbar unter Schnittstellen.",
+ "connect_desc_page": "Empfohlen: Internet + lokal (AutoInterface plus 3 Community-TCP-Knoten). Oder Discovery, nur LAN, oder Schnittstellen später konfigurieren.",
"identity_title": "Identität",
"identity_desc": "Wählen Sie eine neue Identität oder importieren Sie einen vorhandenen Schlüssel, bevor Sie verbinden.",
"identity_desc_page": "Wählen Sie eine neue Identität oder importieren Sie einen vorhandenen Schlüssel, bevor Sie sich mit dem Mesh verbinden.",
@@ -3170,7 +3170,7 @@
"ready_desc": "Alles ist eingerichtet. Reticulum wurde mit Ihrer neuen Konfiguration neu gestartet.",
"ready_desc_page": "MeshChatX ist konfiguriert und Reticulum wurde mit Ihren neuen Einstellungen heiß neu geladen.",
"privacy_title": "Datenschutz und Sicherheit",
- "privacy_desc": "Optionale Härtung für dieses Gerät. Sie können das jederzeit unter Einstellungen → Datenschutz ändern.",
+ "privacy_desc": "Optional. Später unter Einstellungen -> Datenschutz änderbar.",
"privacy_later_hint": "Empfohlen bei sensibler Nutzung. Optionen auszulassen ist für normale Installationen in Ordnung.",
"docker_note": "Reticulum wurde automatisch neu gestartet. Falls etwas nicht stimmt, können Sie MeshChatX über das Menü neu starten.",
"restart_required": "Reticulum neu gestartet",
@@ -3198,7 +3198,7 @@
"mode_change_later": "Sie können die Verbindungseinstellungen jederzeit in den Reticulum-Einstellungen ändern.",
"bootstrap_title": "Bootstrap-Knoten auswählen",
"bootstrap_desc": "Bootstrap-Knoten geben der Erkennung einen Startpunkt. Wählen Sie einen oder mehrere und fahren Sie fort.",
- "bootstrap_pick_random_tcp": "4 zufällige TCP-Knoten wählen",
+ "bootstrap_pick_random_tcp": "3 zufällige TCP-Knoten wählen",
"bootstrap_pick_random_none": "Keine geeigneten TCP-Community-Presets. Presets aktualisieren oder manuell wählen (Zufall nutzt nur Community, nicht Erkennung).",
"bootstrap_pick_random_done": "{count} Bootstrap-Knoten ausgewählt: {names}",
"bootstrap_selected_nodes_heading": "Ausgewählte Knoten",
@@ -3235,11 +3235,19 @@
"auto_propagation_enabled": "Auto-Propagation aktiviert",
"identity_import_empty_file": "Identitätsdatei ist leer.",
"identity_import_file_too_large": "Identitätsdatei ist zu groß.",
- "identity_import_key_only_hint": "Dies importiert nur den Identitätsschlüssel. Um Nachrichten und Einstellungen wiederherzustellen, verwende Über → Aus Datei wiederherstellen mit einer Datenbank-Sicherungs-ZIP.",
+ "identity_import_key_only_hint": "Dies importiert nur den Identitätsschlüssel. Um Nachrichten und Einstellungen wiederherzustellen, verwende Über -> Aus Datei wiederherstellen mit einer Datenbank-Sicherungs-ZIP.",
"identity_file_overrides_base32": "Eine ausgewählte Datei wird anstelle des eingefügten base32-Schlüssels verwendet.",
"identity_import_pending_activate": "Du hast eine Identität importiert, aber noch nicht aktiviert. Jetzt aktivieren?",
"identity_import_pending_kept": "Importierte Identität wurde gespeichert, aber nicht aktiviert. Später unter Identitäten wechseln.",
- "identity_default_delete_failed": "Importierte Identität ist aktiv, aber die Standard-Identität konnte nicht entfernt werden."
+ "identity_default_delete_failed": "Importierte Identität ist aktiv, aber die Standard-Identität konnte nicht entfernt werden.",
+ "privacy_obfuscate_hops_desc": "Wahren Zero-Hop-Ursprung im Mesh verbergen.",
+ "privacy_mode_desc": "Ausgehendes Clearnet-HTTP der App blockieren.",
+ "privacy_telemetry_desc": "Ort/Telemetrie mit vertrauenswürdigen Peers erlauben.",
+ "privacy_android_screenshots_desc": "Screenshots und App-Umschalter-Vorschau blockieren.",
+ "privacy_screen_security_desc": "Fenster vor Screenshots, Recordern und Windows Recall verbergen.",
+ "mode_recommended_title": "Internet + lokal (empfohlen)",
+ "mode_recommended_desc": "Fügt AutoInterface für LAN/WLAN hinzu und wählt 3 zufällige Community-TCP-Bootstraps.",
+ "mode_recommended_added": "Lokales AutoInterface hinzugefügt. Als Nächstes TCP-Bootstraps wählen oder bestätigen."
},
"command_palette": {
"search_placeholder": "Befehle, Routen oder Peers suchen",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "Windows-Bildschirmsicherheit aktivieren?",
- "windows_screen_security_desc": "MeshChatX kann den Windows-Inhaltsschutz nutzen (dasselbe DRM-ähnliche Display-Flag wie Medien-Apps), damit Screenshots, Recorder und Windows Recall das App-Fenster nicht erfassen. Später änderbar unter Einstellungen → Datenschutz.",
+ "windows_screen_security_desc": "MeshChatX kann den Windows-Inhaltsschutz nutzen (dasselbe DRM-ähnliche Display-Flag wie Medien-Apps), damit Screenshots, Recorder und Windows Recall das App-Fenster nicht erfassen. Später änderbar unter Einstellungen -> Datenschutz.",
"windows_screen_security_enable": "Bildschirmsicherheit aktivieren",
"windows_screen_security_later": "Nicht jetzt"
},

diff --git a/meshchatx/src/frontend/locales/en.json b/meshchatx/src/frontend/locales/en.json
index 9cde5b1b..ea3cbf9d 100644
--- a/meshchatx/src/frontend/locales/en.json
+++ b/meshchatx/src/frontend/locales/en.json
@@ -3076,7 +3076,6 @@
"step_2": "2. To **send** a file, get the **Destination Hash** of a listening node, enter the **Local File Path**, and click **Send File**.",
"step_3": "3. To **fetch** a file, get the **Destination Hash** of a node listening with 'Allow Fetch' enabled, enter the **Remote File Path**, and click **Fetch File**.",
"send_file": "Send File",
-
"fetch_file": "Fetch File",
"listen": "Listen",
"destination_hash": "Destination Hash",
@@ -3766,8 +3765,8 @@
"i18n_desc_page": "Full internationalization support for English, German, Italian, Russian, Dutch, French, and Spanish.",
"more_features": "+ many more features!",
"connect": "Connect to the Mesh",
- "connect_desc": "Choose how you want to connect. Discovery and bootstrap nodes can be configured later on the Interfaces page.",
- "connect_desc_page": "Use local LAN discovery or configure custom interfaces from the Interfaces page. Auto-discovery and bootstrap nodes are available there for advanced setup.",
+ "connect_desc": "Recommended: Internet + local (AutoInterface plus 3 community TCP nodes). You can change this later on Interfaces.",
+ "connect_desc_page": "Recommended: Internet + local (AutoInterface plus 3 community TCP nodes). Or use discovery, LAN only, or configure interfaces later.",
"identity_title": "Identity",
"identity_desc": "Choose a new identity or import an existing key before connecting.",
"identity_desc_page": "Choose a new identity or import an existing key before connecting to the mesh.",
@@ -3782,7 +3781,7 @@
"identity_import_failed": "Failed to import identity",
"identity_import_empty_file": "Identity file is empty.",
"identity_import_file_too_large": "Identity file is too large.",
- "identity_import_key_only_hint": "This imports your identity key only. To restore messages and settings, use About → Restore from File with a database backup zip.",
+ "identity_import_key_only_hint": "This imports your identity key only. To restore messages and settings, use About -> Restore from File with a database backup zip.",
"identity_file_overrides_base32": "A selected file will be used instead of the pasted base32 key.",
"identity_import_pending_activate": "You imported an identity but have not activated it yet. Activate it now?",
"identity_import_pending_kept": "Imported identity was saved but not activated. Switch to it later from Identities.",
@@ -3829,8 +3828,13 @@
"ready_desc": "Everything is set up. Reticulum has been restarted with your new configuration.",
"ready_desc_page": "MeshChatX is now configured and Reticulum has been hot-reloaded with your new settings.",
"privacy_title": "Privacy & security",
- "privacy_desc": "Optional hardening for this device. You can change these any time in Settings → Privacy.",
+ "privacy_desc": "Optional. Change later in Settings -> Privacy.",
"privacy_later_hint": "Recommended for sensitive use. Leaving options off is fine for casual installs.",
+ "privacy_obfuscate_hops_desc": "Hide true zero-hop origin on the mesh.",
+ "privacy_mode_desc": "Block outbound clearnet HTTP from the app.",
+ "privacy_telemetry_desc": "Allow location/telemetry with trusted peers.",
+ "privacy_android_screenshots_desc": "Block screenshots and app-switcher previews.",
+ "privacy_screen_security_desc": "Hide this window from screenshots, recorders, and Windows Recall.",
"docker_note": "Reticulum was restarted automatically. If anything looks off, you can restart MeshChatX from the menu.",
"restart_required": "Reticulum Restarted",
"restart_desc_page": "Reticulum was hot-reloaded with your new configuration. No manual restart is required for normal use.",
@@ -3848,8 +3852,11 @@
"no": "No, manual setup",
"discovery_enabled": "Community discovery enabled",
"failed_enable_discovery": "Failed to enable discovery",
+ "mode_recommended_title": "Internet + local (recommended)",
+ "mode_recommended_desc": "Adds AutoInterface for LAN/Wi-Fi and picks 3 random community TCP bootstraps.",
+ "mode_recommended_added": "Local AutoInterface added. Pick or confirm TCP bootstraps next.",
"mode_discovery_title": "Auto-Discovery",
- "mode_discovery_desc": "Find and auto-connect to nearby and internet-reachable Reticulum nodes. You'll pick one or more bootstrap nodes next.",
+ "mode_discovery_desc": "Find and auto-connect to nearby and internet-reachable Reticulum nodes. You'll pick bootstrap nodes next.",
"mode_local_title": "Local Network Only",
"mode_local_desc": "Use Reticulum on your LAN/Wi-Fi only. Adds an AutoInterface for zero-config local mesh.",
"mode_manual_title": "Manual Setup",
@@ -3857,7 +3864,7 @@
"mode_change_later": "You can change connection settings any time from Reticulum settings.",
"bootstrap_title": "Pick Bootstrap Nodes",
"bootstrap_desc": "Bootstrap nodes give discovery a starting point. Select one or more, then continue.",
- "bootstrap_pick_random_tcp": "Pick 4 random TCP nodes",
+ "bootstrap_pick_random_tcp": "Pick 3 random TCP nodes",
"bootstrap_pick_random_none": "No suitable TCP community presets are available. Refresh community presets or pick nodes manually (discovered lists are not used for random pick).",
"bootstrap_pick_random_done": "Selected {count}: {names}",
"bootstrap_selected_nodes_heading": "Selected nodes",
@@ -3958,7 +3965,7 @@
},
"post_install": {
"windows_screen_security_title": "Enable Windows screen security?",
- "windows_screen_security_desc": "MeshChatX can use Windows content protection (the same DRM-style display flag media apps use) so screenshots, recorders, and Windows Recall cannot capture the app window. You can change this later under Settings → Privacy.",
+ "windows_screen_security_desc": "MeshChatX can use Windows content protection (the same DRM-style display flag media apps use) so screenshots, recorders, and Windows Recall cannot capture the app window. You can change this later under Settings -> Privacy.",
"windows_screen_security_enable": "Enable screen security",
"windows_screen_security_later": "Not now"
}

diff --git a/meshchatx/src/frontend/locales/es.json b/meshchatx/src/frontend/locales/es.json
index 8030931f..3df8ffec 100644
--- a/meshchatx/src/frontend/locales/es.json
+++ b/meshchatx/src/frontend/locales/es.json
@@ -3362,8 +3362,8 @@
"i18n_desc_page": "Soporte de internacionalización completo para inglés, alemán, italiano, ruso, holandés, francés y español.",
"more_features": "+ muchas más características!",
"connect": "Conectarse a la malla",
- "connect_desc": "Elija cómo desea conectarse. El descubrimiento y los nodos de arranque se pueden configurar más tarde en la página Interfaces.",
- "connect_desc_page": "Use el descubrimiento de LAN local o configure interfaces personalizadas desde la página Interfaces. El auto-descubrimiento y los nodos de arranque están disponibles allí para la configuración avanzada.",
+ "connect_desc": "Recomendado: Internet + local (AutoInterface más 3 nodos TCP comunitarios). Se puede cambiar después en Interfaces.",
+ "connect_desc_page": "Recomendado: Internet + local (AutoInterface más 3 nodos TCP comunitarios). O use descubrimiento, solo LAN, o configure interfaces después.",
"identity_title": "Identidad",
"identity_desc": "Elija una nueva identidad o importe una clave existente antes de conectar.",
"identity_desc_page": "Elija una nueva identidad o importe una clave existente antes de conectar al mesh.",
@@ -3418,7 +3418,7 @@
"ready_desc": "Todo está preparado. Reticulum ha sido reiniciado con su nueva configuración.",
"ready_desc_page": "MeshChatX está ahora configurado y Reticulum ha sido cargado con su nueva configuración.",
"privacy_title": "Privacidad y seguridad",
- "privacy_desc": "Refuerzo opcional para este dispositivo. Puede cambiarlo en cualquier momento en Ajustes → Privacidad.",
+ "privacy_desc": "Opcional. Cámbielo después en Ajustes -> Privacidad.",
"privacy_later_hint": "Recomendado para uso sensible. Dejar las opciones desactivadas está bien en instalaciones habituales.",
"docker_note": "Reticulum fue reiniciado automáticamente. Si algo se ve apagado, puede reiniciar MeshChatX del menú.",
"restart_required": "Reticulum reiniciado",
@@ -3446,7 +3446,7 @@
"mode_change_later": "Puede cambiar la configuración de conexión en cualquier momento desde la configuración de Reticulum.",
"bootstrap_title": "Seleccionar Nodos Bootstrap",
"bootstrap_desc": "Los nodos de bootstrap dan a descubrimiento un punto de partida. Seleccione uno o más, luego continúe.",
- "bootstrap_pick_random_tcp": "Elegir 4 nodos TCP aleatorios",
+ "bootstrap_pick_random_tcp": "Elegir 3 nodos TCP al azar",
"bootstrap_pick_random_none": "No hay presets TCP comunitarios adecuados. Actualice los presets o elija a mano (el azar solo usa la lista comunitaria, no descubiertos).",
"bootstrap_pick_random_done": "Seleccionados {count}: {names}",
"bootstrap_selected_nodes_heading": "Nodos seleccionados",
@@ -3483,11 +3483,19 @@
"auto_propagation_enabled": "Autopropagación habilitada",
"identity_import_empty_file": "El archivo de identidad está vacío.",
"identity_import_file_too_large": "El archivo de identidad es demasiado grande.",
- "identity_import_key_only_hint": "Esto importa solo tu clave de identidad. Para restaurar mensajes y configuración, usa Acerca de → Restaurar desde archivo con un ZIP de copia de seguridad de la base de datos.",
+ "identity_import_key_only_hint": "Esto importa solo tu clave de identidad. Para restaurar mensajes y configuración, usa Acerca de -> Restaurar desde archivo con un ZIP de copia de seguridad de la base de datos.",
"identity_file_overrides_base32": "Un archivo seleccionado se usará en lugar de la clave base32 pegada.",
"identity_import_pending_activate": "Importaste una identidad pero aún no la has activado. ¿Activar ahora?",
"identity_import_pending_kept": "La identidad importada se guardó pero no se activó. Cambia a ella más tarde desde Identidades.",
- "identity_default_delete_failed": "La identidad importada está activa, pero la identidad predeterminada no se pudo eliminar."
+ "identity_default_delete_failed": "La identidad importada está activa, pero la identidad predeterminada no se pudo eliminar.",
+ "privacy_obfuscate_hops_desc": "Ocultar el origen zero-hop real en la mesh.",
+ "privacy_mode_desc": "Bloquear HTTP clearnet saliente de la app.",
+ "privacy_telemetry_desc": "Permitir ubicación/telemetría con peers de confianza.",
+ "privacy_android_screenshots_desc": "Bloquear capturas y vista previa del conmutador de apps.",
+ "privacy_screen_security_desc": "Ocultar esta ventana de capturas, grabadoras y Windows Recall.",
+ "mode_recommended_title": "Internet + local (recomendado)",
+ "mode_recommended_desc": "Añade AutoInterface para LAN/Wi-Fi y elige 3 TCP comunitarios al azar.",
+ "mode_recommended_added": "AutoInterface local añadido. Elija o confirme bootstraps TCP a continuación."
},
"command_palette": {
"search_placeholder": "Buscar comandos, rutas o pares",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "¿Activar la seguridad de pantalla de Windows?",
- "windows_screen_security_desc": "MeshChatX puede usar la protección de contenido de Windows (la misma marca tipo DRM que usan las apps de medios) para que capturas, grabadoras y Windows Recall no capturen la ventana. Puede cambiarlo después en Ajustes → Privacidad.",
+ "windows_screen_security_desc": "MeshChatX puede usar la protección de contenido de Windows (la misma marca tipo DRM que usan las apps de medios) para que capturas, grabadoras y Windows Recall no capturen la ventana. Puede cambiarlo después en Ajustes -> Privacidad.",
"windows_screen_security_enable": "Activar seguridad de pantalla",
"windows_screen_security_later": "Ahora no"
},

diff --git a/meshchatx/src/frontend/locales/fi.json b/meshchatx/src/frontend/locales/fi.json
index 63a4582b..db69c0dd 100644
--- a/meshchatx/src/frontend/locales/fi.json
+++ b/meshchatx/src/frontend/locales/fi.json
@@ -3584,8 +3584,8 @@
"i18n_desc_page": "Täysi kansainvälistämistuki englanniksi, saksaksi, italiaksi, venäjäksi, hollanniksi, ranskaksi ja espanjaksi.",
"more_features": "+ paljon muita ominaisuuksia!",
"connect": "Yhdistä mesh-verkkoon",
- "connect_desc": "Valitse, miten haluat yhdistää. Löytäminen ja käynnistyssolmut voi määrittää myöhemmin Liitännät-sivulla.",
- "connect_desc_page": "Käytä paikallista LAN-löytämistä tai määritä mukautetut liitännät Liitännät-sivulta. Automaattinen löytäminen ja käynnistyssolmut ovat siellä käytettävissä edistyneeseen asetukseen.",
+ "connect_desc": "Suositus: Internet + paikallinen (AutoInterface sekä 3 yhteisö-TCP-solmua). Voit muuttaa myöhemmin Liitännät-sivulla.",
+ "connect_desc_page": "Suositus: Internet + paikallinen (AutoInterface sekä 3 yhteisö-TCP-solmua). Tai käytä löytämistä, vain LAN, tai määritä liitännät myöhemmin.",
"identity_title": "Identiteetti",
"identity_desc": "Valitse uusi identiteetti tai tuo olemassa oleva avain ennen yhdistämistä.",
"identity_desc_page": "Valitse uusi identiteetti tai tuo olemassa oleva avain ennen yhdistämistä meshiin.",
@@ -3640,7 +3640,7 @@
"ready_desc": "Kaikki on asetettu. Reticulum on käynnistetty uudelleen uudella kokoonpanollasi.",
"ready_desc_page": "MeshChatX on nyt määritetty ja Reticulum on ladattu uudelleen kuumana uusilla asetuksillasi.",
"privacy_title": "Tietosuoja ja turvallisuus",
- "privacy_desc": "Valinnainen kovennus tälle laitteelle. Voit muuttaa näitä milloin tahansa kohdassa Asetukset → Tietosuoja.",
+ "privacy_desc": "Valinnainen. Muuta myöhemmin: Asetukset -> Tietosuoja.",
"privacy_later_hint": "Suositellaan arkaluontoiseen käyttöön. Vaihtoehtojen jättäminen pois on ok tavallisissa asennuksissa.",
"docker_note": "Reticulum käynnistettiin automaattisesti uudelleen. Jos jokin näyttää vialta, voit käynnistää MeshChatX:n uudelleen valikosta.",
"restart_required": "Reticulum käynnistettiin uudelleen",
@@ -3668,7 +3668,7 @@
"mode_change_later": "Voit muuttaa yhteysasetuksia milloin tahansa Reticulum-asetuksista.",
"bootstrap_title": "Valitse bootstrap-solmut",
"bootstrap_desc": "Bootstrap-solmut antavat löydölle lähtökohdan. Valitse yksi tai useampi ja jatka.",
- "bootstrap_pick_random_tcp": "Valitse 4 satunnaista TCP-solmua",
+ "bootstrap_pick_random_tcp": "Valitse 3 satunnaista TCP-solmua",
"bootstrap_pick_random_none": "Sopivia TCP-yhteisön esiasetuksia ei ole saatavilla. Päivitä yhteisön esiasetukset tai valitse solmut manuaalisesti (löydettyjä listoja ei käytetä satunnaisvalintaan).",
"bootstrap_pick_random_done": "Valittu {count}: {names}",
"bootstrap_selected_nodes_heading": "Valitut solmut",
@@ -3705,11 +3705,19 @@
"auto_propagation_enabled": "Automaattinen levitys käytössä",
"identity_import_empty_file": "Identiteettitiedosto on tyhjä.",
"identity_import_file_too_large": "Identiteettitiedosto on liian suuri.",
- "identity_import_key_only_hint": "Tämä tuo vain identiteettiavaimesi. Palauttaaksesi viestit ja asetukset, käytä Tietoja → Palauta tiedostosta tietokannan varmuuskopio-ZIPillä.",
+ "identity_import_key_only_hint": "Tämä tuo vain identiteettiavaimesi. Palauttaaksesi viestit ja asetukset, käytä Tietoja -> Palauta tiedostosta tietokannan varmuuskopio-ZIPillä.",
"identity_file_overrides_base32": "Valittua tiedostoa käytetään liitetyn base32-avaimen sijasta.",
"identity_import_pending_activate": "Toit identiteetin, mutta et ole vielä aktivoinut sitä. Aktivoi nyt?",
"identity_import_pending_kept": "Tuotu identiteetti tallennettiin, mutta sitä ei aktivoitu. Vaihda siihen myöhemmin Identiteetit-osiosta.",
- "identity_default_delete_failed": "Tuotu identiteetti on aktiivinen, mutta oletusidentiteettiä ei voitu poistaa."
+ "identity_default_delete_failed": "Tuotu identiteetti on aktiivinen, mutta oletusidentiteettiä ei voitu poistaa.",
+ "privacy_obfuscate_hops_desc": "Piilota todellinen nolla-hop-alkuperä meshissä.",
+ "privacy_mode_desc": "Estä sovelluksen lähtevä clearnet-HTTP.",
+ "privacy_telemetry_desc": "Salli sijainti/telemetria luotettujen peerien kanssa.",
+ "privacy_android_screenshots_desc": "Estä kuvakaappaukset ja sovellusvaihtajan esikatselu.",
+ "privacy_screen_security_desc": "Piilota ikkuna kuvakaappauksilta, tallentimilta ja Windows Recallilta.",
+ "mode_recommended_title": "Internet + paikallinen (suositus)",
+ "mode_recommended_desc": "Lisää AutoInterface LAN/Wi-Fi:lle ja valitsee 3 satunnaista yhteisö-TCP-bootstrapia.",
+ "mode_recommended_added": "Paikallinen AutoInterface lisätty. Valitse tai vahvista TCP-bootstrapit seuraavaksi."
},
"command_palette": {
"search_placeholder": "Hae komentoja, reittejä tai vertaisia",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "Otetaanko Windowsin näytön suojaus käyttöön?",
- "windows_screen_security_desc": "MeshChatX voi käyttää Windowsin sisällönsuojausta (samaa DRM-tyylistä näyttölippua kuin mediaohjelmat), jotta kuvakaappaukset, tallentimet ja Windows Recall eivät kaappaa sovellusikkunaa. Voit muuttaa tätä myöhemmin kohdassa Asetukset → Tietosuoja.",
+ "windows_screen_security_desc": "MeshChatX voi käyttää Windowsin sisällönsuojausta (samaa DRM-tyylistä näyttölippua kuin mediaohjelmat), jotta kuvakaappaukset, tallentimet ja Windows Recall eivät kaappaa sovellusikkunaa. Voit muuttaa tätä myöhemmin kohdassa Asetukset -> Tietosuoja.",
"windows_screen_security_enable": "Ota näytön suojaus käyttöön",
"windows_screen_security_later": "Ei nyt"
},

diff --git a/meshchatx/src/frontend/locales/fr.json b/meshchatx/src/frontend/locales/fr.json
index e1b96657..97a7fd64 100644
--- a/meshchatx/src/frontend/locales/fr.json
+++ b/meshchatx/src/frontend/locales/fr.json
@@ -3362,8 +3362,8 @@
"i18n_desc_page": "Appui complet à l'internationalisation pour l'anglais, l'allemand, l'italien, le russe, le néerlandais, le français et l'espagnol.",
"more_features": "+ beaucoup plus de fonctionnalités!",
"connect": "Connectez-vous au Mesh",
- "connect_desc": "Choisissez comment vous connecter. La découverte et les nœuds de bootstrap peuvent être configurés plus tard sur la page Interfaces.",
- "connect_desc_page": "Utilisez la découverte LAN locale ou configurez des interfaces personnalisées depuis la page Interfaces. L'auto-découverte et les nœuds de bootstrap y sont disponibles pour une configuration avancée.",
+ "connect_desc": "Recommandé : Internet + local (AutoInterface plus 3 nœuds TCP communautaires). Modifiable plus tard dans Interfaces.",
+ "connect_desc_page": "Recommandé : Internet + local (AutoInterface plus 3 nœuds TCP communautaires). Ou découverte, LAN seul, ou configurer les interfaces plus tard.",
"identity_title": "Identité",
"identity_desc": "Choisissez une nouvelle identité ou importez une clé existante avant de vous connecter.",
"identity_desc_page": "Choisissez une nouvelle identité ou importez une clé existante avant de rejoindre le réseau.",
@@ -3418,7 +3418,7 @@
"ready_desc": "Tout est arrangé. Reticulum a été redémarré avec votre nouvelle configuration.",
"ready_desc_page": "MeshChatX est maintenant configuré et Reticulum a été chargé à chaud avec vos nouveaux paramètres.",
"privacy_title": "Confidentialité et sécurité",
- "privacy_desc": "Renforcement facultatif pour cet appareil. Vous pouvez changer ces options à tout moment dans Paramètres → Confidentialité.",
+ "privacy_desc": "Facultatif. Modifiable plus tard dans Paramètres -> Confidentialité.",
"privacy_later_hint": "Recommandé pour un usage sensible. Laisser les options désactivées convient aux installations courantes.",
"docker_note": "Le réticulum a été redémarré automatiquement. Si quelque chose vous regarde, vous pouvez redémarrer MeshChatX depuis le menu.",
"restart_required": "Reticulum Recommencé",
@@ -3446,7 +3446,7 @@
"mode_change_later": "Vous pouvez modifier les paramètres de connexion à tout moment à partir des paramètres de Reticulum.",
"bootstrap_title": "Choisir des nœuds de bootstrap",
"bootstrap_desc": "Les nœuds de bootstrap donnent un point de départ à la découverte. Sélectionnez un ou plusieurs, puis continuez.",
- "bootstrap_pick_random_tcp": "Choisir 4 nœuds TCP au hasard",
+ "bootstrap_pick_random_tcp": "Choisir 3 nœuds TCP au hasard",
"bootstrap_pick_random_none": "Aucun préréglage TCP communautaire adapté. Actualisez les préréglages ou choisissez à la main (le tirage n'utilise que la liste communautaire, pas la découverte).",
"bootstrap_pick_random_done": "{count} sélectionné(s) : {names}",
"bootstrap_selected_nodes_heading": "Nœuds sélectionnés",
@@ -3483,11 +3483,19 @@
"auto_propagation_enabled": "Autopropagation activée",
"identity_import_empty_file": "Le fichier d'identité est vide.",
"identity_import_file_too_large": "Le fichier d'identité est trop volumineux.",
- "identity_import_key_only_hint": "Cela importe uniquement votre clé d'identité. Pour restaurer les messages et les paramètres, utilisez À propos → Restaurer à partir d'un fichier avec un ZIP de sauvegarde de la base de données.",
+ "identity_import_key_only_hint": "Cela importe uniquement votre clé d'identité. Pour restaurer les messages et les paramètres, utilisez À propos -> Restaurer à partir d'un fichier avec un ZIP de sauvegarde de la base de données.",
"identity_file_overrides_base32": "Un fichier sélectionné sera utilisé à la place de la clé base32 collée.",
"identity_import_pending_activate": "Vous avez importé une identité mais ne l'avez pas encore activée. L'activer maintenant ?",
"identity_import_pending_kept": "L'identité importée a été enregistrée mais pas activée. Changez plus tard depuis Identités.",
- "identity_default_delete_failed": "L'identité importée est active, mais l'identité par défaut n'a pas pu être supprimée."
+ "identity_default_delete_failed": "L'identité importée est active, mais l'identité par défaut n'a pas pu être supprimée.",
+ "privacy_obfuscate_hops_desc": "Masquer la vraie origine zero-hop sur le mesh.",
+ "privacy_mode_desc": "Bloquer le HTTP clearnet sortant de l'app.",
+ "privacy_telemetry_desc": "Autoriser localisation/télémétrie avec des pairs de confiance.",
+ "privacy_android_screenshots_desc": "Bloquer captures et aperçu du sélecteur d'apps.",
+ "privacy_screen_security_desc": "Masquer cette fenêtre aux captures, enregistreurs et Windows Recall.",
+ "mode_recommended_title": "Internet + local (recommandé)",
+ "mode_recommended_desc": "Ajoute AutoInterface pour LAN/Wi-Fi et choisit 3 bootstraps TCP communautaires au hasard.",
+ "mode_recommended_added": "AutoInterface local ajouté. Choisissez ou confirmez les bootstraps TCP ensuite."
},
"command_palette": {
"search_placeholder": "Commandes de recherche, itinéraires ou pairs",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "Activer la sécurité d’écran Windows ?",
- "windows_screen_security_desc": "MeshChatX peut utiliser la protection de contenu Windows (le même indicateur d’affichage de type DRM que les apps multimédias) pour que les captures, enregistreurs et Windows Recall ne capturent pas la fenêtre. Modifiable plus tard dans Paramètres → Confidentialité.",
+ "windows_screen_security_desc": "MeshChatX peut utiliser la protection de contenu Windows (le même indicateur d’affichage de type DRM que les apps multimédias) pour que les captures, enregistreurs et Windows Recall ne capturent pas la fenêtre. Modifiable plus tard dans Paramètres -> Confidentialité.",
"windows_screen_security_enable": "Activer la sécurité d’écran",
"windows_screen_security_later": "Pas maintenant"
},

diff --git a/meshchatx/src/frontend/locales/it.json b/meshchatx/src/frontend/locales/it.json
index c49ca1ff..df8e4b40 100644
--- a/meshchatx/src/frontend/locales/it.json
+++ b/meshchatx/src/frontend/locales/it.json
@@ -3362,8 +3362,8 @@
"i18n_desc_page": "Supporto completo all'internazionalizzazione per Inglese, Tedesco, Italiano, Russo, Olandese, Francese e Spagnolo.",
"more_features": "+ molte altre funzioni!",
"connect": "Connettiti alla Mesh",
- "connect_desc": "Scegli come connetterti. Discovery e nodi di bootstrap possono essere configurati in seguito nella pagina Interfacce.",
- "connect_desc_page": "Usa la discovery LAN locale o configura interfacce personalizzate dalla pagina Interfacce. Auto-discovery e nodi di bootstrap sono disponibili lì per la configurazione avanzata.",
+ "connect_desc": "Consigliato: Internet + locale (AutoInterface più 3 nodi TCP community). Modificabile dopo in Interfacce.",
+ "connect_desc_page": "Consigliato: Internet + locale (AutoInterface più 3 nodi TCP community). Oppure discovery, solo LAN, o configura le interfacce dopo.",
"identity_title": "Identità",
"identity_desc": "Scegli una nuova identità o importa una chiave esistente prima di connetterti.",
"identity_desc_page": "Scegli una nuova identità o importa una chiave esistente prima di connetterti alla mesh.",
@@ -3418,7 +3418,7 @@
"ready_desc": "Tutto è configurato. Reticulum è stato riavviato con la nuova configurazione.",
"ready_desc_page": "MeshChatX è ora configurato e Reticulum è stato ricaricato a caldo con le nuove impostazioni.",
"privacy_title": "Privacy e sicurezza",
- "privacy_desc": "Rafforzamento facoltativo per questo dispositivo. Puoi modificarlo in qualsiasi momento in Impostazioni → Privacy.",
+ "privacy_desc": "Facoltativo. Modificabile in Impostazioni -> Privacy.",
"privacy_later_hint": "Consigliato per usi sensibili. Lasciare le opzioni disattivate va bene per installazioni comuni.",
"docker_note": "Reticulum è stato riavviato automaticamente. Se qualcosa non va, riavvia MeshChatX dal menu.",
"restart_required": "Reticulum riavviato",
@@ -3446,7 +3446,7 @@
"mode_change_later": "Puoi cambiare le impostazioni di connessione in qualsiasi momento dalle impostazioni Reticulum.",
"bootstrap_title": "Scegli nodi di bootstrap",
"bootstrap_desc": "I nodi di bootstrap danno alla scoperta un punto di partenza. Selezionane uno o più e continua.",
- "bootstrap_pick_random_tcp": "Scegli 4 nodi TCP casuali",
+ "bootstrap_pick_random_tcp": "Scegli 3 nodi TCP a caso",
"bootstrap_pick_random_none": "Nessun preset TCP della community adatto. Aggiorna i preset o scegli manualmente (la selezione casuale usa solo la community, non il rilevamento).",
"bootstrap_pick_random_done": "Selezionati {count}: {names}",
"bootstrap_selected_nodes_heading": "Nodi selezionati",
@@ -3483,11 +3483,19 @@
"auto_propagation_enabled": "Auto-propagazione abilitata",
"identity_import_empty_file": "Il file di identità è vuoto.",
"identity_import_file_too_large": "Il file di identità è troppo grande.",
- "identity_import_key_only_hint": "Questo importa solo la tua chiave d'identità. Per ripristinare messaggi e impostazioni, usa Informazioni → Ripristina da file con un backup ZIP del database.",
+ "identity_import_key_only_hint": "Questo importa solo la tua chiave d'identità. Per ripristinare messaggi e impostazioni, usa Informazioni -> Ripristina da file con un backup ZIP del database.",
"identity_file_overrides_base32": "Un file selezionato verrà utilizzato al posto della chiave base32 incollata.",
"identity_import_pending_activate": "Hai importato un'identità ma non l'hai ancora attivata. Attivarla ora?",
"identity_import_pending_kept": "L'identità importata è stata salvata ma non attivata. Passaci più tardi da Identità.",
- "identity_default_delete_failed": "L'identità importata è attiva, ma l'identità predefinita non può essere rimossa."
+ "identity_default_delete_failed": "L'identità importata è attiva, ma l'identità predefinita non può essere rimossa.",
+ "privacy_obfuscate_hops_desc": "Nascondi la vera origine zero-hop sulla mesh.",
+ "privacy_mode_desc": "Blocca HTTP clearnet in uscita dall'app.",
+ "privacy_telemetry_desc": "Consenti posizione/telemetria con peer attendibili.",
+ "privacy_android_screenshots_desc": "Blocca screenshot e anteprima dello switcher app.",
+ "privacy_screen_security_desc": "Nascondi questa finestra a screenshot, recorder e Windows Recall.",
+ "mode_recommended_title": "Internet + locale (consigliato)",
+ "mode_recommended_desc": "Aggiunge AutoInterface per LAN/Wi-Fi e sceglie 3 bootstrap TCP community a caso.",
+ "mode_recommended_added": "AutoInterface locale aggiunto. Scegli o conferma i bootstrap TCP dopo."
},
"command_palette": {
"search_placeholder": "Cerca comandi, percorsi o peer",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "Attivare la sicurezza schermo di Windows?",
- "windows_screen_security_desc": "MeshChatX può usare la protezione contenuti di Windows (lo stesso flag display in stile DRM delle app multimediali) così screenshot, registratori e Windows Recall non catturano la finestra. Modificabile in seguito in Impostazioni → Privacy.",
+ "windows_screen_security_desc": "MeshChatX può usare la protezione contenuti di Windows (lo stesso flag display in stile DRM delle app multimediali) così screenshot, registratori e Windows Recall non catturano la finestra. Modificabile in seguito in Impostazioni -> Privacy.",
"windows_screen_security_enable": "Attiva sicurezza schermo",
"windows_screen_security_later": "Non ora"
},

diff --git a/meshchatx/src/frontend/locales/nl.json b/meshchatx/src/frontend/locales/nl.json
index 54df48f8..fc0b38b9 100644
--- a/meshchatx/src/frontend/locales/nl.json
+++ b/meshchatx/src/frontend/locales/nl.json
@@ -3362,8 +3362,8 @@
"i18n_desc_page": "Volledige internationaliseringssteun voor Engels, Duits, Italiaans, Russisch, Nederlands, Frans en Spaans.",
"more_features": "+ nog veel meer functies!",
"connect": "Verbinding met de Mesh",
- "connect_desc": "Kies hoe u wilt verbinden. Discovery en bootstrapknooppunten kunt u later configureren op de Interfaces-pagina.",
- "connect_desc_page": "Gebruik lokale LAN-discovery of configureer aangepaste interfaces via de Interfaces-pagina. Auto-discovery en bootstrapknooppunten zijn daar beschikbaar voor geavanceerde setup.",
+ "connect_desc": "Aanbevolen: Internet + lokaal (AutoInterface plus 3 community-TCP-nodes). Later te wijzigen op Interfaces.",
+ "connect_desc_page": "Aanbevolen: Internet + lokaal (AutoInterface plus 3 community-TCP-nodes). Of discovery, alleen LAN, of later interfaces configureren.",
"identity_title": "Identiteit",
"identity_desc": "Kies een nieuwe identiteit of importeer een bestaande sleutel voordat u verbinding maakt.",
"identity_desc_page": "Kies een nieuwe identiteit of importeer een bestaande sleutel voordat u met het mesh verbindt.",
@@ -3418,7 +3418,7 @@
"ready_desc": "Alles is geregeld. Reticulum is opnieuw gestart met uw nieuwe configuratie.",
"ready_desc_page": "MeshChatX is nu geconfigureerd en Reticulum is hot-reloaded met uw nieuwe instellingen.",
"privacy_title": "Privacy en beveiliging",
- "privacy_desc": "Optionele verharding voor dit apparaat. Je kunt dit altijd wijzigen in Instellingen → Privacy.",
+ "privacy_desc": "Optioneel. Later te wijzigen in Instellingen -> Privacy.",
"privacy_later_hint": "Aanbevolen bij gevoelig gebruik. Opties uit laten staan is prima voor gewone installaties.",
"docker_note": "Reticulum werd automatisch herstart. Als er iets misgaat, kunt u MeshChatX opnieuw starten vanuit het menu.",
"restart_required": "Reticulum opnieuw gestart",
@@ -3446,7 +3446,7 @@
"mode_change_later": "U kunt de verbindingsinstellingen op elk moment wijzigen vanuit de instellingen van Reticulum.",
"bootstrap_title": "Kies Bootstrap-nodes",
"bootstrap_desc": "Bootstrap knooppunten geven ontdekking een startpunt. Selecteer één of meer, ga dan verder.",
- "bootstrap_pick_random_tcp": "Kies 4 willekeurige TCP-knooppunten",
+ "bootstrap_pick_random_tcp": "Kies 3 willekeurige TCP-nodes",
"bootstrap_pick_random_none": "Geen geschikte TCP-community-presets. Vernieuw presets of kies handmatig (willekeur kiest alleen community, niet ontdekking).",
"bootstrap_pick_random_done": "{count} geselecteerd: {names}",
"bootstrap_selected_nodes_heading": "Geselecteerde knooppunten",
@@ -3483,11 +3483,19 @@
"auto_propagation_enabled": "Auto-propagatie ingeschakeld",
"identity_import_empty_file": "Identiteitsbestand is leeg.",
"identity_import_file_too_large": "Identiteitsbestand is te groot.",
- "identity_import_key_only_hint": "Dit importeert alleen je identiteitssleutel. Om berichten en instellingen te herstellen, gebruik Over → Herstellen uit bestand met een database-backup-ZIP.",
+ "identity_import_key_only_hint": "Dit importeert alleen je identiteitssleutel. Om berichten en instellingen te herstellen, gebruik Over -> Herstellen uit bestand met een database-backup-ZIP.",
"identity_file_overrides_base32": "Een geselecteerd bestand wordt gebruikt in plaats van de geplakte base32-sleutel.",
"identity_import_pending_activate": "Je hebt een identiteit geïmporteerd maar nog niet geactiveerd. Nu activeren?",
"identity_import_pending_kept": "Geïmporteerde identiteit is opgeslagen maar niet geactiveerd. Schakel later over via Identiteiten.",
- "identity_default_delete_failed": "Geïmporteerde identiteit is actief, maar de standaardidentiteit kon niet worden verwijderd."
+ "identity_default_delete_failed": "Geïmporteerde identiteit is actief, maar de standaardidentiteit kon niet worden verwijderd.",
+ "privacy_obfuscate_hops_desc": "Verberg echte zero-hop-herkomst op de mesh.",
+ "privacy_mode_desc": "Blokkeer uitgaande clearnet-HTTP van de app.",
+ "privacy_telemetry_desc": "Sta locatie/telemetrie toe met vertrouwde peers.",
+ "privacy_android_screenshots_desc": "Blokkeer screenshots en app-wisselaar-preview.",
+ "privacy_screen_security_desc": "Verberg dit venster voor screenshots, recorders en Windows Recall.",
+ "mode_recommended_title": "Internet + lokaal (aanbevolen)",
+ "mode_recommended_desc": "Voegt AutoInterface toe voor LAN/Wi-Fi en kiest 3 willekeurige community-TCP-bootstraps.",
+ "mode_recommended_added": "Lokale AutoInterface toegevoegd. Kies of bevestig daarna TCP-bootstraps."
},
"command_palette": {
"search_placeholder": "Zoekopdrachten, routes of collega's",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "Windows-schermbeveiliging inschakelen?",
- "windows_screen_security_desc": "MeshChatX kan Windows-inhoudsbescherming gebruiken (dezelfde DRM-achtige displayvlag als media-apps) zodat screenshots, recorders en Windows Recall het appvenster niet vastleggen. Later te wijzigen onder Instellingen → Privacy.",
+ "windows_screen_security_desc": "MeshChatX kan Windows-inhoudsbescherming gebruiken (dezelfde DRM-achtige displayvlag als media-apps) zodat screenshots, recorders en Windows Recall het appvenster niet vastleggen. Later te wijzigen onder Instellingen -> Privacy.",
"windows_screen_security_enable": "Schermbeveiliging inschakelen",
"windows_screen_security_later": "Niet nu"
},

diff --git a/meshchatx/src/frontend/locales/ru.json b/meshchatx/src/frontend/locales/ru.json
index 737ff6e3..90812a7a 100644
--- a/meshchatx/src/frontend/locales/ru.json
+++ b/meshchatx/src/frontend/locales/ru.json
@@ -3114,8 +3114,8 @@
"i18n_desc_page": "Полная поддержка интернационализации для английского, немецкого, итальянского, русского, нидерландского, французского и испанского языков.",
"more_features": "+ еще много функций!",
"connect": "Подключение к Mesh",
- "connect_desc": "Выберите способ подключения. Обнаружение и начальные узлы можно настроить позже на странице «Интерфейсы».",
- "connect_desc_page": "Используйте локальное обнаружение в LAN или настройте свои интерфейсы на странице «Интерфейсы». Автообнаружение и начальные узлы доступны там для расширенной настройки.",
+ "connect_desc": "Рекомендуется: Интернет + локально (AutoInterface и 3 community TCP-узла). Позже можно изменить в «Интерфейсы».",
+ "connect_desc_page": "Рекомендуется: Интернет + локально (AutoInterface и 3 community TCP-узла). Или обнаружение, только LAN, или настроить интерфейсы позже.",
"identity_title": "Личность",
"identity_desc": "Выберите новую личность или импортируйте существующий ключ перед подключением.",
"identity_desc_page": "Выберите новую личность или импортируйте существующий ключ перед подключением к mesh.",
@@ -3170,7 +3170,7 @@
"ready_desc": "Все настроено. Reticulum перезапущен с новой конфигурацией.",
"ready_desc_page": "MeshChatX настроен, Reticulum выполнил горячую перезагрузку с новыми параметрами.",
"privacy_title": "Конфиденциальность и безопасность",
- "privacy_desc": "Необязательное усиление для этого устройства. Можно изменить в любой момент в Настройки → Конфиденциальность.",
+ "privacy_desc": "Необязательно. Позже: Настройки -> Конфиденциальность.",
"privacy_later_hint": "Рекомендуется при чувствительном использовании. Оставить параметры выключенными нормально для обычных установок.",
"docker_note": "Reticulum был перезапущен автоматически. Если что-то не так, перезапустите MeshChatX через меню.",
"restart_required": "Reticulum перезапущен",
@@ -3198,7 +3198,7 @@
"mode_change_later": "Настройки подключения можно изменить в любое время в параметрах Reticulum.",
"bootstrap_title": "Выберите начальные узлы",
"bootstrap_desc": "Начальные узлы дают обнаружению точку входа. Выберите один или несколько и продолжайте.",
- "bootstrap_pick_random_tcp": "Выбрать 4 случайных TCP-узла",
+ "bootstrap_pick_random_tcp": "Выбрать 3 случайных TCP-узла",
"bootstrap_pick_random_none": "Нет подходящих TCP-пресетов сообщества. Обновите пресеты или выберите вручную (случайный выбор только из списка сообщества, не из обнаружения).",
"bootstrap_pick_random_done": "Выбрано {count}: {names}",
"bootstrap_selected_nodes_heading": "Выбранные узлы",
@@ -3235,11 +3235,19 @@
"auto_propagation_enabled": "Авторетрансляция включена",
"identity_import_empty_file": "Файл идентичности пуст.",
"identity_import_file_too_large": "Файл идентичности слишком большой.",
- "identity_import_key_only_hint": "Импортируется только ключ идентичности. Для восстановления сообщений и настроек используйте «О программе» → «Восстановить из файла» с ZIP-архивом резервной копии базы данных.",
+ "identity_import_key_only_hint": "Импортируется только ключ идентичности. Для восстановления сообщений и настроек используйте «О программе» -> «Восстановить из файла» с ZIP-архивом резервной копии базы данных.",
"identity_file_overrides_base32": "Выбранный файл будет использован вместо вставленного ключа base32.",
"identity_import_pending_activate": "Вы импортировали идентичность, но ещё не активировали её. Активировать сейчас?",
"identity_import_pending_kept": "Импортированная идентичность сохранена, но не активирована. Переключитесь на неё позже в разделе «Идентичности».",
- "identity_default_delete_failed": "Импортированная идентичность активна, но идентичность по умолчанию не может быть удалена."
+ "identity_default_delete_failed": "Импортированная идентичность активна, но идентичность по умолчанию не может быть удалена.",
+ "privacy_obfuscate_hops_desc": "Скрыть истинный zero-hop источник в mesh.",
+ "privacy_mode_desc": "Блокировать исходящий clearnet HTTP приложения.",
+ "privacy_telemetry_desc": "Разрешить локацию/телеметрию с доверенными пирами.",
+ "privacy_android_screenshots_desc": "Блокировать снимки и превью переключателя приложений.",
+ "privacy_screen_security_desc": "Скрыть окно от снимков, записи и Windows Recall.",
+ "mode_recommended_title": "Интернет + локально (рекомендуется)",
+ "mode_recommended_desc": "Добавляет AutoInterface для LAN/Wi-Fi и выбирает 3 случайных community TCP bootstrap.",
+ "mode_recommended_added": "Локальный AutoInterface добавлен. Далее выберите или подтвердите TCP bootstrap."
},
"command_palette": {
"search_placeholder": "Команды, маршруты или узлы",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "Включить защиту экрана Windows?",
- "windows_screen_security_desc": "MeshChatX может использовать защиту содержимого Windows (тот же DRM-подобный флаг отображения, что у медиаприложений), чтобы снимки, запись и Windows Recall не захватывали окно. Позже можно изменить в Настройки → Конфиденциальность.",
+ "windows_screen_security_desc": "MeshChatX может использовать защиту содержимого Windows (тот же DRM-подобный флаг отображения, что у медиаприложений), чтобы снимки, запись и Windows Recall не захватывали окно. Позже можно изменить в Настройки -> Конфиденциальность.",
"windows_screen_security_enable": "Включить защиту экрана",
"windows_screen_security_later": "Не сейчас"
},

diff --git a/meshchatx/src/frontend/locales/zh.json b/meshchatx/src/frontend/locales/zh.json
index e3a1b6dc..280ed460 100644
--- a/meshchatx/src/frontend/locales/zh.json
+++ b/meshchatx/src/frontend/locales/zh.json
@@ -3362,8 +3362,8 @@
"i18n_desc_page": "完全支持英语、德语、意大利语、俄语、荷兰语、法语、西班牙语和中文的国际化。",
"more_features": "+更多功能!",
"connect": "连接到网格",
- "connect_desc": "选择连接方式。发现与引导节点可稍后在“接口”页面配置。",
- "connect_desc_page": "使用本地局域网发现,或在“接口”页面配置自定义接口。自动发现与引导节点可在该页进行高级设置。",
+ "connect_desc": "推荐:互联网 + 本地(AutoInterface 加 3 个社区 TCP 节点)。稍后可在“接口”页面更改。",
+ "connect_desc_page": "推荐:互联网 + 本地(AutoInterface 加 3 个社区 TCP 节点)。也可使用发现、仅局域网,或稍后配置接口。",
"identity_title": "身份",
"identity_desc": "在连接前选择新建身份或导入已有密钥。",
"identity_desc_page": "在连接网络前选择新建身份或导入已有密钥。",
@@ -3418,7 +3418,7 @@
"ready_desc": "一切已设置。Reticulum 已随您的新配置重新启动。",
"ready_desc_page": "MeshChatX 现已配置,Reticulum 已随您的新设置热重载。",
"privacy_title": "隐私与安全",
- "privacy_desc": "此设备的可选加固。可随时在 设置 → 隐私 中更改。",
+ "privacy_desc": "可选。稍后可在 设置 -> 隐私 中更改。",
"privacy_later_hint": "敏感用途建议开启。日常安装可保持关闭。",
"docker_note": "Reticulum 会自动重新启动。如果有任何更改,您可以从菜单中重新启动 MeshChatX。",
"restart_required": "Reticulum 重新启动",
@@ -3446,7 +3446,7 @@
"mode_change_later": "您可以随时从 Reticulum 设置中更改连接设置。",
"bootstrap_title": "选择引导节点",
"bootstrap_desc": "引导节点为发现提供起点。选择一个或多个,然后继续。",
- "bootstrap_pick_random_tcp": "随机选择 4 个 TCP 节点",
+ "bootstrap_pick_random_tcp": "随机选择 3 个 TCP 节点",
"bootstrap_pick_random_none": "没有可用的社区 TCP 预设。请刷新预设或手动选择(随机仅从社区列表选取,不含发现节点)。",
"bootstrap_pick_random_done": "已选择 {count} 个:{names}",
"bootstrap_selected_nodes_heading": "已选节点",
@@ -3483,11 +3483,19 @@
"auto_propagation_enabled": "已启用自动传播",
"identity_import_empty_file": "身份文件为空。",
"identity_import_file_too_large": "身份文件太大。",
- "identity_import_key_only_hint": "此操作仅导入您的身份密钥。要恢复消息和设置,请使用「关于」→「从文件恢复」并使用数据库备份 ZIP。",
+ "identity_import_key_only_hint": "此操作仅导入您的身份密钥。要恢复消息和设置,请使用「关于」->「从文件恢复」并使用数据库备份 ZIP。",
"identity_file_overrides_base32": "选中的文件将替代粘贴的 base32 密钥使用。",
"identity_import_pending_activate": "您已导入一个身份但尚未激活。立即激活?",
"identity_import_pending_kept": "导入的身份已保存但未激活。稍后可在「身份」中切换。",
- "identity_default_delete_failed": "导入的身份已激活,但无法删除默认身份。"
+ "identity_default_delete_failed": "导入的身份已激活,但无法删除默认身份。",
+ "privacy_obfuscate_hops_desc": "在 mesh 上隐藏真实的零跳来源。",
+ "privacy_mode_desc": "阻止应用出站 clearnet HTTP。",
+ "privacy_telemetry_desc": "允许与可信对等方共享位置/遥测。",
+ "privacy_android_screenshots_desc": "阻止截图和应用切换器预览。",
+ "privacy_screen_security_desc": "对截图、录屏和 Windows Recall 隐藏此窗口。",
+ "mode_recommended_title": "互联网 + 本地(推荐)",
+ "mode_recommended_desc": "添加 LAN/Wi-Fi 的 AutoInterface,并随机选择 3 个社区 TCP 引导节点。",
+ "mode_recommended_added": "已添加本地 AutoInterface。接下来选择或确认 TCP 引导节点。"
},
"command_palette": {
"search_placeholder": "搜索命令、路径或端点",
@@ -3860,7 +3868,7 @@
},
"post_install": {
"windows_screen_security_title": "启用 Windows 屏幕安全?",
- "windows_screen_security_desc": "MeshChatX 可使用 Windows 内容保护(与媒体应用相同的 DRM 风格显示标志),使截图、录屏和 Windows Recall 无法捕获应用窗口。之后可在 设置 → 隐私 中更改。",
+ "windows_screen_security_desc": "MeshChatX 可使用 Windows 内容保护(与媒体应用相同的 DRM 风格显示标志),使截图、录屏和 Windows Recall 无法捕获应用窗口。之后可在 设置 -> 隐私 中更改。",
"windows_screen_security_enable": "启用屏幕安全",
"windows_screen_security_later": "暂不"
},

diff --git a/scripts/build/reticulum_docs_bundle.json b/scripts/build/reticulum_docs_bundle.json
index dded1e5f..f22f0f35 100644
--- a/scripts/build/reticulum_docs_bundle.json
+++ b/scripts/build/reticulum_docs_bundle.json
@@ -1,6 +1,6 @@
{
"dest": "meshchatx/public/reticulum-docs-bundled/current",
- "fetched_utc": "2026-07-10T17:45:25Z",
+ "fetched_utc": "2026-07-24T10:01:13Z",
"html_files": 206,
"skipped_binary_files": 2,
"source_url": "https://codeload.github.com/markqvist/reticulum_website/zip/refs/heads/master"

diff --git a/tests/electron/safeConsole.test.js b/tests/electron/safeConsole.test.js
index b2f3d398..3c58937e 100644
--- a/tests/electron/safeConsole.test.js
+++ b/tests/electron/safeConsole.test.js
@@ -61,12 +61,8 @@ describe("safeConsole", () => {
it("shouldMirrorStdout is false without a TTY unless forced", () => {
expect(shouldMirrorStdout({ stdout: { isTTY: false } }, {})).toBe(false);
expect(shouldMirrorStdout({ stdout: { isTTY: true } }, {})).toBe(true);
- expect(
- shouldMirrorStdout({ stdout: { isTTY: false } }, { MESHCHAT_FORCE_STDOUT_LOG: "1" }),
- ).toBe(true);
- expect(
- shouldMirrorStdout({ stdout: { isTTY: true } }, { MESHCHAT_DISABLE_STDOUT_LOG: "1" }),
- ).toBe(false);
+ expect(shouldMirrorStdout({ stdout: { isTTY: false } }, { MESHCHAT_FORCE_STDOUT_LOG: "1" })).toBe(true);
+ expect(shouldMirrorStdout({ stdout: { isTTY: true } }, { MESHCHAT_DISABLE_STDOUT_LOG: "1" })).toBe(false);
});
it("createMainProcessLogger appends durable lines and skips non-TTY stdout", () => {

diff --git a/tests/frontend/clipboardUtils.test.js b/tests/frontend/clipboardUtils.test.js
index 849c0d23..ce9e702b 100644
--- a/tests/frontend/clipboardUtils.test.js
+++ b/tests/frontend/clipboardUtils.test.js
@@ -93,7 +93,7 @@ describe("clipboardUtils", () => {
constructor(items) {
this.items = items;
}
- },
+ }
);
const prev = window.isSecureContext;
Object.defineProperty(window, "isSecureContext", { configurable: true, value: true });


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────